#include <stddef.h> // 包含 NULL 的定义
#include "extraConvert.h"

Bool T_CONV(Bool enable, const void* inValue, TConvType inType, void* outValue, TConvType outType) {
  if(!enable) // 禁止执行，直接返回 false
    return false;

  if(inValue == NULL || outValue == NULL)
    return false;

  int64_t tmp = 0;

  // 输入统一转 int64_t
  switch(inType) {
    case T_TYPE_SINT:
      tmp = *(const SInt*) inValue;
      break;
    case T_TYPE_INT:
      tmp = *(const Int*) inValue;
      break;
    case T_TYPE_DINT:
      tmp = *(const DInt*) inValue;
      break;
    case T_TYPE_USINT:
      tmp = *(const USInt*) inValue;
      break;
    case T_TYPE_UINT:
      tmp = *(const UInt*) inValue;
      break;
    case T_TYPE_UDINT:
      tmp = *(const UDInt*) inValue;
      break;
    case T_TYPE_LINT:
      tmp = *(const LInt*) inValue;
      break;
    case T_TYPE_ULINT:
      tmp = *(const ULInt*) inValue;
      break;
    case T_TYPE_TIME:
      tmp = *(const Time*) inValue;
      break; // ms
    case T_TYPE_LTIME:
      tmp = *(const LTime*) inValue;
      break; // ms
    case T_TYPE_DATE:
      tmp = (int64_t) (*(const Date*) inValue) * 24LL * 3600 * 1000;
      break; // 天->ms
    case T_TYPE_TOD:
      tmp = *(const TimeOfDay*) inValue;
      break; // 一天毫秒
    case T_TYPE_LTOD:
      tmp = *(const ULInt*) inValue;
      break; // 一天毫秒
    default:
      return false;
  }

  // 输出类型转换
  switch(outType) {
    case T_TYPE_SINT:
      *(SInt*) outValue = (SInt) tmp;
      break;
    case T_TYPE_INT:
      *(Int*) outValue = (Int) tmp;
      break;
    case T_TYPE_DINT:
      *(DInt*) outValue = (DInt) tmp;
      break;
    case T_TYPE_USINT:
      *(USInt*) outValue = (USInt) tmp;
      break;
    case T_TYPE_UINT:
      *(UInt*) outValue = (UInt) tmp;
      break;
    case T_TYPE_UDINT:
      *(UDInt*) outValue = (UDInt) tmp;
      break;
    case T_TYPE_LINT:
      *(LInt*) outValue = (LInt) tmp;
      break;
    case T_TYPE_ULINT:
      *(ULInt*) outValue = (ULInt) tmp;
      break;
    case T_TYPE_TIME:
      *(Time*) outValue = (Time) tmp;
      break; // 毫秒
    case T_TYPE_LTIME:
      *(LTime*) outValue = (LTime) tmp;
      break; // 毫秒
    case T_TYPE_DATE:
      *(Date*) outValue = (Date) (tmp / (24LL * 3600 * 1000));
      break;
    case T_TYPE_TOD:
      *(TimeOfDay*) outValue = (TimeOfDay) (tmp % (24LL * 3600 * 1000));
      break;
    case T_TYPE_LTOD:
      *(ULInt*) outValue = (ULInt) (tmp % (24LL * 3600 * 1000));
      break;

    default:
      return false;
  }

  return true;
}
